﻿using System;
using System.Collections.Generic;
using System.Linq;

namespace MMonitor.PM6750
{
    public class SendCodeTransV2
    {
        private byte[] PackageHead;
        private byte[] PackageContent;
        private byte PackageSum;
        //控制命令格式：0x55 0xaa CMD P1 P2 SUM
        //其中：0x55 0xaa 为数据头，CMD为命令字节，P1 P2为参数,SUM为校验和
        //SUM=(CMD+P1+P2)%256；
        //private readonly byte[] _packageHead = {0x55, 0xAA};//指令包头
        public SendCodeTransV2()
        {
            PackageHead = new byte[] {0x55, 0xAA};
            PackageContent = new byte[] {0x00, 0x00, 0x00};
            PackageSum = 0x00;
        }
        /// <summary>
        /// 生成命令控代码-私有
        /// </summary>
        /// <returns>一条完整的控制字符</returns>
        protected byte[] GenerateControlCode()
        {
            //计算CMD+P1+P2的和
            byte sum = PackageContent.Aggregate<byte, byte>(0, (current, bt) => (byte)(current + bt));
            sum = Convert.ToByte(sum % 256);//计算校验和

            /*!-- 生成控制指令串*/
            var resultList = new List<byte>();
            resultList.AddRange(PackageHead);
            resultList.AddRange(PackageContent);
            resultList.Add(sum);
            return resultList.ToArray();
        }
        /// <summary>
        /// 启动测量-私有
        /// </summary>
        /// <param name="p1">参数P1</param>
        /// <param name="p2">参数P2</param>
        /// <returns></returns>
        private byte[] GetTestStart(byte p1, byte p2)
        {
            PackageContent = new byte[] { 0x01, p1, p2 };//启动测量指令
            return GenerateControlCode();
        }
        /// <summary>
        /// 外部扩展控制命令-本版本
        /// </summary>
        /// <param name="cmd">CMD命令字节值</param>
        /// <param name="p1">参数P1</param>
        /// <param name="p2">参数P2</param>
        /// <returns></returns>
        public byte[] GetInterFaceCommandCode(byte cmd, byte p1, byte p2)
        {
            PackageContent = new byte[] { cmd, p1, p2 };
            return GenerateControlCode();
        }
        /// <summary>
        /// 启动一次手动血压测量
        /// </summary>
        /// <param name="p1">P1 = 0（成人150），P1 = 1（成人180），P1 = 3（成人140），P1 = 4（成人160），P1 = 2 (儿童70) P1 = 5 (儿童100) P1 = 6 (儿童120)</param>
        /// <returns></returns>
        public byte[] GetStartOnceManualTestCode(byte p1)
        {
            return GetTestStart(p1, 0x00);
        }
        /// <summary>
        /// 启动或取消自动（或连续）测量
        /// </summary>
        /// <param name="p2">自动测量:0x01:1分钟;0x02:2分钟;0x03:3分钟;0x04:4分钟;0x05:5分钟;0x10:10分钟;0x30:30分钟;0x60:60分钟;0x90:90分钟;0x6f:取消自动测量;0x7f:连续测量(快速测量);0x80:取消连续测量</param>
        /// <returns></returns>
        public byte[] GetStartOrCancleAutoTestCode(byte p2)
        {
            return GetTestStart(0xE0, p2);
        }
        /// <summary>
        /// 启动漏气检测
        /// </summary>
        /// <returns></returns>
        public byte[] GetStartBlowingTestCode()
        {
            return GetTestStart(0x60, 0x00);
        }
        /// <summary>
        /// 血压模块复位
        /// </summary>
        /// <returns></returns>
        public byte[] GetResetBloodModuleCode()
        {
            return GetTestStart(0xA0, 0x00);
        }

        /// <summary>
        /// 取消血压测量
        /// </summary>
        /// <returns></returns>
        public byte[] GetCancleBloodPressureTestCode()
        {
            PackageContent = new byte[] { 0x02, 0x00, 0x00 };
            return GenerateControlCode();
        }
        /// <summary>
        /// 血压校准(平均压位置显示袖带实时压)
        /// </summary>
        /// <returns></returns>
        public byte[] GetCalibrateBloodPressureCode()
        {
            PackageContent = new byte[] { 0x03, 0x00, 0x00 };
            return GenerateControlCode();
        }
        /// <summary>
        /// 漏气检测
        /// </summary>
        /// <param name="preChargeGasValue">预充气压力值，单位：mmHg</param>
        /// <returns></returns>
        public byte[] GetBlowingTestCode(byte preChargeGasValue)
        {
            preChargeGasValue /= 2;
            PackageContent = new byte[] { 0x04, preChargeGasValue, 0x00 };
            return GenerateControlCode();
        }
        /// <summary>
        /// 体温较准
        /// </summary>
        /// <param name="isTemperature1">True为体温1的值</param>
        /// <param name="calibateValue">矫正偏差值0.1°C的值为1</param>
        /// <returns></returns>
        public byte[] GetCalibrateCodeTemperatureCode(bool isTemperature1, byte calibateValue)
        {
            var cmd = (byte)(isTemperature1 ? 0x06 : 0x07);
            PackageContent = new byte[] { cmd, calibateValue, 0x00 };
            return GenerateControlCode();
        }
        /// <summary>
        /// 心电控制
        /// </summary>
        /// <param name="leadc">导联选择（000Ⅰ﹑001 Ⅱ﹑010 Ⅲ﹑011 aVR﹑100aVL﹑101aVF﹑110 V﹑111 MCL1）</param>
        /// <param name="gain">增益选择（00:x0.5﹑01:x1﹑10:x2）</param>
        /// <param name="mode">方式选择（00：诊断﹑01：监护﹑10手术）</param>
        /// <returns></returns>
        public byte[] GetEcgControlCode(byte[] leadc, byte[] gain, byte[] mode)
        {
            //合并命令字节
            var controlByte =
                Convert.ToByte((mode[0] * Math.Pow(2, 6)) + (mode[1] * Math.Pow(2, 5)) + (gain[0] * Math.Pow(2, 4)) +
                               (gain[1] * Math.Pow(2, 3)) + (leadc[0] * Math.Pow(2, 2)) + (leadc[1] * 2) + leadc[2]);
            PackageContent = new byte[] { 0x08, controlByte, 0x00 };
            return GenerateControlCode();
        }
        /// <summary>
        /// 呼吸控制
        /// </summary>
        /// <param name="p1">增益（0:x0.5;1:x1;2:x2;3:x4）</param>
        /// <returns></returns>
        public byte[] GetBreathControlCode(byte p1)
        {

            PackageContent = new byte[] { 0x09, p1, 0x00 };
            return GenerateControlCode();
        }
        /// <summary>
        /// 获取监护仪软件版本号
        /// </summary>
        /// <returns></returns>
        public byte[] GetVersionCode()
        {
            PackageContent = new byte[] { 0x0F, 0x80, 0x80 };
            return GenerateControlCode();
        }
    }
}
